{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%pip install --upgrade --quiet  dashscope\n",
    "%pip install -qU zhipuai"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_community.llms import Tongyi\n",
    "from dotenv import load_dotenv\n",
    "import os\n",
    "from langchain.schema import (\n",
    "    AIMessage,\n",
    "    HumanMessage,\n",
    "    SystemMessage\n",
    ")\n",
    "# 加载 .env 文件\n",
    "load_dotenv()  # 默认会加载位于项目根目录的 .env 文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "llm = Tongyi(dashscope_api_key=os.getenv(\"DASHSCOPE_API_KEY\"), model_name=\"qwen-plus\")\n",
    "print(llm.model_name)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_community.chat_models.tongyi import ChatTongyi\n",
    "from langchain_core.messages import HumanMessage\n",
    "chatLLM = ChatTongyi(\n",
    "    streaming=True,\n",
    ")\n",
    "messages = [\n",
    "    (\"system\", \"你是一名专业的翻译家，可以将用户的中文翻译为英文。\"),\n",
    "    (\"human\", \"我喜欢编程。\"),\n",
    "]\n",
    "res = chatLLM.stream([HumanMessage(content=\"你好请跟我进行十次对话\")], streaming=True)\n",
    "for r in res:\n",
    "    print(\"chat resp:\", r)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "messages = [\n",
    "    SystemMessage(content=\"Return only a JSON object as a response with no explanation text\"),\n",
    "    HumanMessage(content=\"Generate a JSON response object containing a brief description and release year for the movie '上甘岭'\")\n",
    "    \n",
    "]\n",
    "\n",
    "response = chatLLM(messages)\n",
    "print(response)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "messages2 = [\n",
    "    SystemMessage(content=\"只返回一个JSON对象作为响应，不包含解释文本\"),\n",
    "    HumanMessage(content=\"生成一个JSON响应对象，其中包含电影《上甘岭》的简要描述和发行年份。\")\n",
    "]\n",
    "\n",
    "response2 = chatLLM(messages2)\n",
    "print(response2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "batch_messages = [\n",
    "    [\n",
    "        SystemMessage(content=\"Return only a JSON object as a response with no explanation text\"),\n",
    "        HumanMessage(content=\"Generate a JSON response object containing a brief description and release year for the movie 'Inception'\")\n",
    "    ],\n",
    "    [\n",
    "        SystemMessage(content=\"Return only a JSON object as a response with no explanation text\"),\n",
    "        HumanMessage(content=\"Generate a JSON response object containing a brief description and release year for the movie 'Avatar'\")\n",
    "    ]\n",
    "]\n",
    "\n",
    "result = chatLLM.generate(batch_messages)\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import Any, Dict, List, Optional\n",
    "\n",
    "from langchain_core.embeddings import Embeddings\n",
    "from langchain_core.utils import get_from_dict_or_env\n",
    "from pydantic import BaseModel, Field, model_validator\n",
    "import os\n",
    "from zhipuai import ZhipuAI\n",
    "\n",
    "class ZhipuAIEmbeddings(BaseModel, Embeddings):\n",
    "    \"\"\"ZhipuAI embedding model integration.\n",
    "\n",
    "    Setup:\n",
    "\n",
    "        To use, you should have the ``zhipuai`` python package installed, and the\n",
    "        environment variable ``ZHIPU_API_KEY`` set with your API KEY.\n",
    "\n",
    "        More instructions about ZhipuAi Embeddings, you can get it\n",
    "        from  https://open.bigmodel.cn/dev/api#vector\n",
    "\n",
    "        .. code-block:: bash\n",
    "\n",
    "            pip install -U zhipuai\n",
    "            export ZHIPU_API_KEY=\"your-api-key\"\n",
    "\n",
    "    Key init args — completion params:\n",
    "        model: Optional[str]\n",
    "            Name of ZhipuAI model to use.\n",
    "        api_key: str\n",
    "            Automatically inferred from env var `ZHIPU_API_KEY` if not provided.\n",
    "\n",
    "    See full list of supported init args and their descriptions in the params section.\n",
    "\n",
    "    Instantiate:\n",
    "\n",
    "        .. code-block:: python\n",
    "\n",
    "            from langchain_community.embeddings import ZhipuAIEmbeddings\n",
    "\n",
    "            embed = ZhipuAIEmbeddings(\n",
    "                model=\"embedding-2\",\n",
    "                # api_key=\"...\",\n",
    "            )\n",
    "\n",
    "    Embed single text:\n",
    "        .. code-block:: python\n",
    "\n",
    "            input_text = \"The meaning of life is 42\"\n",
    "            embed.embed_query(input_text)\n",
    "\n",
    "        .. code-block:: python\n",
    "\n",
    "            [-0.003832892, 0.049372625, -0.035413884, -0.019301128, 0.0068899863, 0.01248398, -0.022153955, 0.006623926, 0.00778216, 0.009558191, ...]\n",
    "\n",
    "\n",
    "    Embed multiple text:\n",
    "        .. code-block:: python\n",
    "\n",
    "            input_texts = [\"This is a test query1.\", \"This is a test query2.\"]\n",
    "            embed.embed_documents(input_texts)\n",
    "\n",
    "        .. code-block:: python\n",
    "\n",
    "            [\n",
    "                [0.0083934665, 0.037985895, -0.06684559, -0.039616987, 0.015481004, -0.023952313, ...],\n",
    "                [-0.02713102, -0.005470169, 0.032321047, 0.042484466, 0.023290444, 0.02170547, ...]\n",
    "            ]\n",
    "    \"\"\"  # noqa: E501\n",
    "\n",
    "    client: Any = Field(default=None, exclude=True)  #: :meta private:\n",
    "    model: str = Field(default=\"embedding-2\")\n",
    "    \"\"\"Model name\"\"\"\n",
    "    api_key: str\n",
    "    \"\"\"Automatically inferred from env var `ZHIPU_API_KEY` if not provided.\"\"\"\n",
    "    dimensions: Optional[int] = None\n",
    "    \"\"\"The number of dimensions the resulting output embeddings should have.\n",
    "\n",
    "    Only supported in `embedding-3` and later models.\n",
    "    \"\"\"\n",
    "\n",
    "    @model_validator(mode=\"before\")\n",
    "    @classmethod\n",
    "    def validate_environment(cls, values: Dict) -> Any:\n",
    "        \"\"\"Validate that auth token exists in environment.\"\"\"\n",
    "        values[\"api_key\"] = get_from_dict_or_env(values, \"api_key\", \"ZHIPUAI_API_KEY\")\n",
    "        try:\n",
    "            from zhipuai import ZhipuAI\n",
    "\n",
    "            values[\"client\"] = ZhipuAI(api_key=values[\"api_key\"])\n",
    "        except ImportError:\n",
    "            raise ImportError(\n",
    "                \"Could not import zhipuai python package.\"\n",
    "                \"Please install it with `pip install zhipuai`.\"\n",
    "            )\n",
    "        return values\n",
    "\n",
    "\n",
    "\n",
    "    def embed_query(self, text: str) -> List[float]:\n",
    "        \"\"\"\n",
    "        Embeds a text using the AutoVOT algorithm.\n",
    "\n",
    "        Args:\n",
    "            text: A text to embed.\n",
    "\n",
    "        Returns:\n",
    "            Input document's embedded list.\n",
    "        \"\"\"\n",
    "        resp = self.embed_documents([text])\n",
    "        return resp[0]\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "    def embed_documents(self, texts: List[str]) -> List[List[float]]:\n",
    "        \"\"\"\n",
    "        Embeds a list of text documents using the AutoVOT algorithm.\n",
    "\n",
    "        Args:\n",
    "            texts: A list of text documents to embed.\n",
    "\n",
    "        Returns:\n",
    "            A list of embeddings for each document in the input list.\n",
    "            Each embedding is represented as a list of float values.\n",
    "        \"\"\"\n",
    "        if self.dimensions is not None:\n",
    "            resp = self.client.embeddings.create(\n",
    "                model=self.model,\n",
    "                input=texts,\n",
    "                dimensions=self.dimensions,\n",
    "            )\n",
    "        else:\n",
    "            resp = self.client.embeddings.create(model=self.model, input=texts)\n",
    "        embeddings = [r.embedding for r in resp.data]\n",
    "        return embeddings\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [],
   "source": [
    "embeddings = ZhipuAIEmbeddings(\n",
    "    model=\"embedding-2\",\n",
    "    api_key=os.getenv(\"ZHIPU_API_KEY\"),\n",
    "    dimensions=1024\n",
    ")\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create a vector store with a sample text\n",
    "from langchain.vectorstores import InMemoryVectorStore\n",
    "text = \"LangChain is the framework for building context-aware reasoning applications\"\n",
    "vector_store = InMemoryVectorStore(embeddings)\n",
    "# 创建向量存储\n",
    "print(vector_store)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_core.documents import Document\n",
    "\n",
    "document_1 = Document(id=\"1\", page_content=\"foo\", metadata={\"baz\": \"bar\"})\n",
    "document_2 = Document(id=\"2\", page_content=\"thud\", metadata={\"bar\": \"baz\"})\n",
    "document_3 = Document(id=\"3\", page_content=\"i will be deleted :(\")\n",
    "documents = [document_1, document_2, document_3]\n",
    "vector_store.add_documents(documents=documents)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 创建一个向量存储并使用示例文本\n",
    "\n",
    "# 从 langchain.vectorstores 模块导入 InMemoryVectorStore 类\n",
    "from langchain.vectorstores import InMemoryVectorStore\n",
    "\n",
    "# 定义示例文本，用于向量化和存储\n",
    "# 这里 text 是一个包含多个字符串的列表，每个字符串代表一个文档\n",
    "text = [\n",
    "    \"LangChain is the framework for building context-aware reasoning applications\",\n",
    "    \"A list of embeddings for each document in the input list\",\n",
    "    \"深圳市，简称“深”，别称鹏城，广东省辖地级市、副省级市 [285]、国家计划单列市，超大城市 [267]\"\n",
    "]  # 示例文本内容\n",
    "\n",
    "# 使用 InMemoryVectorStore 的 from_texts 方法创建一个向量存储实例\n",
    "# 参数说明：\n",
    "# - texts 是包含多个文本的列表\n",
    "# - embedding 是用于将文本转换为向量的嵌入模型，假设 embeddings 已在其他地方定义\n",
    "vector_store = InMemoryVectorStore.from_texts(\n",
    "    texts=text,  # 直接传递 text 列表，而不是 [text]，因为 text 已经是一个列表\n",
    "    embedding=embeddings,  # 使用预先定义的 embeddings 对象作为嵌入模型\n",
    ")\n",
    "\n",
    "# 将向量存储转换为检索器，以便执行相似性检索\n",
    "# 设置 search_kwargs={\"k\": 1} 以仅返回排名第一的文档\n",
    "retriever = vector_store.as_retriever(search_kwargs={\"k\": 1})  # 获取检索器对象，并设置返回文档的数量为1\n",
    "\n",
    "# 定义查询字符串，用于检索最相似的文本\n",
    "query = \"中国?\"  # 查询内容\n",
    "\n",
    "# 使用检索器根据查询字符串检索相关文档\n",
    "try:\n",
    "    retrieved_documents = retriever.invoke(query)  # 执行检索操作，返回相关文档列表\n",
    "except Exception as e:\n",
    "    print(f\"检索过程中发生错误: {e}\")\n",
    "    retrieved_documents = []\n",
    "\n",
    "# 使用检索器根据查询字符串检索相关文档\n",
    "retrieved_documents = retriever.invoke(query)  # 调用 invoke 方法执行检索操作，返回相关文档列表\n",
    "\n",
    "# 检查是否有检索到的文档\n",
    "if retrieved_documents:\n",
    "    # 打印排名第一的文档的内容\n",
    "    print(\"排名第一的检索到的文档内容：\")\n",
    "    print(retrieved_documents[0].page_content)  # 输出第一个检索到的文档内容\n",
    "else:\n",
    "    print(\"未检索到相关文档。\")  # 如果没有检索到文档，输出提示信息\n",
    "\n",
    "\n",
    "# 使用嵌入模型将单个文本转换为向量\n",
    "# 这里我们选择 text 列表中的第一个元素作为示例\n",
    "single_text = text[0]  # 选择第一个文本进行向量化\n",
    "single_vector = embeddings.embed_query(single_text)  # 调用 embed_query 方法将单个文本转换为向量表示\n",
    "\n",
    "# 打印生成的向量\n",
    "print(\"文本的向量表示：\")\n",
    "print(single_vector)  # 将向量转换为字符串并输出，便于查看其数值表示\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 仅仅使用embeding\n",
    "from sklearn.metrics.pairwise import cosine_similarity\n",
    "import numpy as np\n",
    "\n",
    "\n",
    "vectors = embeddings.embed_documents(text)\n",
    "# 生成查询的嵌入\n",
    "query_embedding = embeddings.embed_query(\"介绍深圳\")\n",
    "\n",
    "# 转换查询嵌入为二维数组\n",
    "query_embedding_2d = np.array(query_embedding).reshape(1, -1)\n",
    "\n",
    "# 计算每个文档与查询的余弦相似度\n",
    "similarities = cosine_similarity(query_embedding_2d, vectors)\n",
    "\n",
    "# 输出每个文档与查询的相似度分数\n",
    "print(similarities)\n",
    "\n",
    "# 找到最相似的文档\n",
    "most_similar_doc_index = np.argmax(similarities)\n",
    "print(f\"最相似的文档索引为: {most_similar_doc_index}\")\n",
    "print(f\"最相似的文档内容为: {text[most_similar_doc_index]}\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 使用 documents 生成一系列文档的嵌入\n",
    "documents = [\n",
    "    (\n",
    "        \"北京市（Beijing），简称“京”，古称燕京、北平，是中华人民共和国首都、直辖市、\"\n",
    "        \"国家中心城市、超大城市，[185]国务院批复确定的中国政治中心、文化中心、国际交往中心、\"\n",
    "        \"科技创新中心，[1]中国历史文化名城和古都之一，世界一线城市。[3][142][189]截至2023年10月，\"\n",
    "        \"北京市下辖16个区，总面积16410.54平方千米。[82][195][197]2022年末，北京市常住人口2184.3万人。[167]\"\n",
    "    ),\n",
    "    (\n",
    "        \"深圳市，简称“深”，别称鹏城，广东省辖地级市、副省级市 [285]、国家计划单列市，超大城市 [267]，\"\n",
    "        \"国务院批复确定的经济特区、全国性经济中心城市 [1]和国家创新型城市，粤港澳大湾区核心引擎城市之一 [242]。\"\n",
    "        \"截至2022年末，全市下辖9个区，总面积1997.47平方千米，常住人口1766.18万人 [204][257]。\"\n",
    "    )\n",
    "]\n",
    "\n",
    "doc_result = embeddings.embed_documents(documents)\n",
    "print(doc_result)\n",
    "import numpy as np\n",
    "\n",
    "doc_array = np.array(doc_result)\n",
    "print(doc_array.shape)\n",
    "\n",
    "from sklearn.metrics.pairwise import cosine_similarity\n",
    "import numpy as np\n",
    "\n",
    "# 生成查询的嵌入\n",
    "query_embedding = embeddings.embed_query(\"介绍深圳\")\n",
    "\n",
    "# 转换查询嵌入为二维数组\n",
    "query_embedding_2d = np.array(query_embedding).reshape(1, -1)\n",
    "\n",
    "# 计算每个文档与查询的余弦相似度\n",
    "similarities = cosine_similarity(query_embedding_2d, doc_result)\n",
    "\n",
    "# 输出每个文档与查询的相似度分数\n",
    "print(similarities)\n",
    "\n",
    "# 找到最相似的文档\n",
    "most_similar_doc_index = np.argmax(similarities)\n",
    "print(f\"最相似的文档索引为: {most_similar_doc_index}\")\n",
    "print(f\"最相似的文档内容为: {documents[most_similar_doc_index]}\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.19"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
